﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using int64_t = System.Int64;

namespace ArgusLib.FFmpeg.avcodec.Interop
{
	/// <summary>
	/// This structure stores compressed data. It is typically exported by demuxers
	/// and then passed as input to decoders, or received as output from encoders and
	/// then passed to muxers.
	///
	/// For video, it should typically contain one compressed frame. For audio it may
	/// contain several compressed frames.
	///
	/// AVPacket is one of the few structs in FFmpeg, whose size is a part of public
	/// ABI. Thus it may be allocated on stack and no new fields can be added to it
	/// without libavcodec and libavformat major bump.
	///
	/// The semantics of data ownership depends on the buf or destruct (deprecated)
	/// fields. If either is set, the packet data is dynamically allocated and is
	/// valid indefinitely until av_free_packet() is called (which in turn calls
	/// av_buffer_unref()/the destruct callback to free the data). If neither is set,
	/// the packet data is typically backed by some static buffer somewhere and is
	/// only valid for a limited time (e.g. until the next read call when demuxing).
	///
	/// The side data is always allocated with av_malloc() and is freed in
	/// av_free_packet().
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public class AVPacketNative
	{
		/// <summary>
		/// A reference to the reference-counted buffer where the packet data is
		/// stored.
		/// May be NULL, then the packet data is not reference-counted.
		/// </summary>
		public IntPtr buf;

		/// <summary>
		/// Presentation timestamp in AVStream->time_base units; the time at which
		/// the decompressed packet will be presented to the user.
		/// Can be AV_NOPTS_VALUE if it is not stored in the file.
		/// pts MUST be larger or equal to dts as presentation cannot happen before
		/// decompression, unless one wants to view hex dumps. Some formats misuse
		/// the terms dts and pts/cts to mean something different. Such timestamps
		/// must be converted to true pts/dts before they are stored in AVPacket.
		/// </summary>
		public int64_t pts;

		/// <summary>
		/// Decompression timestamp in AVStream->time_base units; the time at which
		/// the packet is decompressed.
		/// Can be AV_NOPTS_VALUE if it is not stored in the file.
		/// </summary>
		public int64_t dts;

		public IntPtr data;
		public int size;
		public int stream_index;

		/// <summary>
		/// A combination of AV_PKT_FLAG values
		/// </summary>
		public int flags;

		/// <summary>
		/// Additional packet data that can be provided by the container.
		/// Packet can contain several types of side information.
		/// </summary>
		public IntPtr side_data;

		int side_data_elems;

		/// <summary>
		/// Duration of this packet in AVStream->time_base units, 0 if unknown.
		/// Equals next_pts - this_pts in presentation order.
		/// </summary>
		public int duration;

		#if FF_API_DESTRUCT_PACKET
		attribute_deprecated
		void  (*destruct)(struct AVPacket *);
		attribute_deprecated
		void  *priv;
		#endif

		/// <summary>
		/// byte position in stream, -1 if unknown
		/// </summary>
		public int64_t pos;

		/// <summary>
		/// Time difference in AVStream->time_base units from the pts of this
		/// packet to the point at which the output from the decoder has converged
		/// independent from the availability of previous frames. That is, the
		/// frames are virtually identical no matter if decoding started from
		/// the very first frame or from this keyframe.
		/// Is AV_NOPTS_VALUE if unknown.
		/// This field is not the display duration of the current packet.
		/// This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
		/// set.
		///
		/// The purpose of this field is to allow seeking in streams that have no
		/// keyframes in the conventional sense. It corresponds to the
		/// recovery point SEI in H.264 and match_time_delta in NUT. It is also
		/// essential for some types of subtitle streams to ensure that all
		/// subtitles are correctly displayed after seeking.
		/// </summary>
		public int64_t convergence_duration;
	}
}